// good ,机器人零件分配问题 - 背包DP解法
#include <bits/stdc++.h>
using namespace std;
#define LL long long
const int MAXN = 500 + 5;      // 最大零件数量
int n;                         // 零件总数
int w[MAXN], h[MAXN], b[MAXN]; // w:重量, h:头部欢乐值, b: 身体欢乐值
LL f[MAXN * MAXN];             // DP数组，f[j]表示头部重量为j时的最大欢乐值

int main() {
  // 输入零件数量
  cin >> n;
  int m = 0; // 所有零件总重量

  // 输入每个零件的重量、头部欢乐值、身体欢乐值
  for (int i = 1; i <= n; ++i) {
    cin >> w[i] >> h[i] >> b[i];
    m += w[i]; // 累加总重量
  }

  // 初始化DP数组
  // f[0] = 0: 头部重量为0时，所有零件都放在尾部，欢乐值为0
  f[0] = 0;

  // 其他状态初始化为负无穷，表示不可达状态
  for (int i = 1; i <= m; ++i)
    f[i] = -1e18;

  // 动态规划过程 - 01背包思想
  for (int i = 1; i <= n; ++i) { // 遍历每个零件
    // 从大到小遍历重量，避免重复选择（01背包优化）
    for (int j = m; j >= 0; --j) {

      // 转移1：将零件i放在尾部
      // 头部重量j不变，欢乐值增加b[i]
      f[j] = f[j] + b[i];

      // 转移2：将零件i放在头部（前提：当前头部重量j >= 零件i的重量w[i]）
      if (j >= w[i])
        // 比较两种选择：放在尾部 vs 放在头部
        // 放在头部：从f[j-w[i]]状态转移过来，欢乐值增加h[i]
        f[j] = max(f[j], f[j - w[i]] + h[i]);
    }
  }

  // 寻找最优解
  LL ans = -1e18;
  // 只考虑头部重量不超过总重量一半的情况（平衡条件）
  for (int j = 0; j <= m / 2; ++j)
    ans = max(ans, f[j]);

  cout << ans; // 输出最大欢乐值

  return 0;
}